home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / telecomm / fnordadl / fn132src.zoo / citutil / popular.c < prev    next >
C/C++ Source or Header  |  1991-09-02  |  6KB  |  287 lines

  1. /*
  2.  * popular.c -- Rough popularity estimator for rooms
  3.  *
  4.  * 90May09 AA    add -a flag for allowing all rooms to be shown
  5.  * 88Feb06 orc    add -s flag to sort rooms by # messages, etc
  6.  * 87Apr07 orc    changes for 2.??
  7.  * 87Mar01 orc    ST hacks...
  8.  * 86May12 HAW    Version 2.1.
  9.  * 86Apr?? HAW    Version 2.0.
  10.  * 86Apr07 HAW    Version 1.1.
  11.  * 86Apr01 HAW    Created.
  12.  */
  13.  
  14. #include "ctdl.h"
  15. #include "net.h"
  16. #include "room.h"
  17. #include "log.h"
  18. #include "msg.h"
  19. #include "config.h"
  20. #include "citlib.h"
  21.  
  22. struct cTab {
  23.     int c_rmno;
  24.     int c_forgot, c_messages;
  25. };
  26.  
  27. struct cTab *countTab;
  28.  
  29. int domesg = FALSE;
  30. int allowall = FALSE;
  31. int sorted = FALSE;
  32. #define    SORTSIZE    0x1
  33. #define    SORTZED        0x2
  34.  
  35. int thisRoom = LOBBY;
  36.  
  37. int logfl;                 /* log file descriptor        */
  38.  
  39. char *program = "popular";
  40. static char *LINE = "\
  41. --------------------------------------------------------------------------";
  42.  
  43. char inNet = TRUE;
  44. char loggedIn = FALSE;
  45. char usingWCprotocol = 0;
  46. int (*sendPFchar)();
  47.  
  48. void handle();
  49.  
  50. /*
  51.  * decoy routines to avoid linker hysterics
  52.  */
  53. mPrintf() {}
  54. void doCR() {}
  55. mAbort() {}
  56. xprintf() {}    /* because something somewhere is linking in libroute.o */
  57.  
  58. /*
  59.  * decoy variables to avoid linker hysterics
  60.  */
  61. char prevChar;
  62. struct aRoom roomBuf;        /* to avoid linking in libroom.o    */
  63. char echo;
  64.  
  65. /*
  66.  * display() -- displays results
  67.  */
  68. void
  69. display(int activeLogs, int activeForgots)
  70. {
  71.     int rover;
  72.     int rmno;
  73.     int PublicRoomCount = 0, ForgetCount = 0;
  74.     char whatm = 'a';
  75.  
  76.     printf("%s @ %s\n\n", formDate(), tod(TRUE));
  77.  
  78.     printf(
  79. "Out of a log of %d entries, %d are in use; %d (%d%%) have used [Z]forget.\n\n",
  80.  cfg.logsize, activeLogs, activeForgots, (100* activeForgots) / activeLogs);
  81.  
  82.     printf("%35s%16s%10s\n", "# of Users", "% of Total", "% of [Z]");
  83.     printf("%-25s%-16s%-13s%s", "Room name", "Forgetting", "User Base",
  84.                     "Users");
  85.     if (domesg)
  86.     printf("%15s", "Messages");
  87.     printf("\n%s\n", LINE);
  88.  
  89.     for (rover = 0;  rover < MAXROOMS;    rover++) {
  90.     rmno = countTab[rover].c_rmno;
  91.     if (readbit(roomTab[rmno],INUSE) && 
  92.         (allowall || readbit(roomTab[rmno],PUBLIC))) {
  93.         PublicRoomCount++;
  94.         ForgetCount += countTab[rover].c_forgot;
  95.         printf("%s%-28s%-15d%-9d%3d",
  96.         (readbit(roomTab[rmno],PUBLIC) ? "  " : "* "),
  97.         roomTab[rmno].rtname, countTab[rover].c_forgot,
  98.    (activeLogs != 0) ? (100 * countTab[rover].c_forgot) / activeLogs : 0,
  99.    (activeForgots != 0) ? (100 * countTab[rover].c_forgot) / activeForgots : 0);
  100.         if (domesg) printf("%14d", countTab[rover].c_messages);
  101.         putchar('\n');
  102.     }
  103.     }
  104.  
  105.     ForgetCount /= PublicRoomCount;
  106.     printf("%s\n\n", LINE);
  107.     printf("There are %d %srooms, ", PublicRoomCount, (allowall ? "" :
  108.     "public "));
  109.     printf("an average %d forgetting them (%d%% and %d%%)\n\n",
  110.                     ForgetCount,
  111.     (activeLogs != 0) ? (100 * ForgetCount) / activeLogs : 0,
  112.     (activeForgots != 0) ? (100 * ForgetCount) / activeForgots : 0);
  113. }
  114.  
  115. /*
  116.  * doMessages() -- loops thru msg file until finished.
  117.  */
  118. void
  119. doMessages(void)
  120. {
  121.     long msg, firstMessage;
  122.     unsigned total;         /* For stat keeping. */
  123.     PATHBUF msgFile;
  124.  
  125.     fprintf(stderr, "Mulching...\n");
  126.  
  127.     ctdlfile(msgFile, cfg.msgdir, "ctdlmsg.sys");
  128.     if ((msgfl = dopen(msgFile, O_RDWR)) < 0)
  129.     crashout("no %s", msgFile);
  130.  
  131.     msgseek(0, 0);
  132.     getmessage();
  133.     msg = msgBuf.mbid;
  134.     fprintf(stderr, "%ld\r", msg);
  135.     firstMessage = msg;
  136.     handle();
  137.     
  138.     total = 0;
  139.     do {
  140.     total++;
  141.     getmessage();
  142.     msg = msgBuf.mbid;
  143.     fprintf(stderr, "%ld\r", msg);
  144.     handle();
  145.     } while (msg != firstMessage);
  146.  
  147.     printf("%u message%s.\n", total, (total!=1)?"s":"");
  148. }
  149.  
  150. void
  151. doflags(int argc, char **argv)
  152. {
  153.     int i;
  154.     char *p;
  155.  
  156.     for (i = 0; i < MAXROOMS; i++) {
  157.     countTab[i].c_rmno = i;
  158.     countTab[i].c_forgot = countTab[i].c_messages = 0;
  159.     }
  160.  
  161.     while (argc > 1) {
  162.     --argc;
  163.     if ( *(p=argv[argc]) == '-') {
  164.         while (*++p) switch (tolower(*p)) {
  165.         case 'm':
  166.         domesg = TRUE;
  167.         break;
  168.         case 'a':
  169.         allowall = TRUE;
  170.         break;
  171.         case 's':
  172.         switch (tolower(p[1])) {
  173.         case 'z':
  174.             p++;
  175.             sorted |= SORTZED;
  176.             break;
  177.         case 'b':
  178.             p++;
  179.             sorted |= (SORTZED|SORTSIZE);
  180.             break;
  181.         case 'p':
  182.             p++;
  183.         default:
  184.             sorted |= SORTSIZE;
  185.             break;
  186.         }
  187.         break;
  188.         default:
  189.         fprintf(stderr,"usage: popular [-ams[z|p|b]]\n");
  190.         if (fromdesk())
  191.             hitkey();
  192.         exit(255);
  193.         }
  194.     }
  195.     }
  196.     if (!domesg)        /* not -m so we can't sort by size... */
  197.     sorted &= ~SORTSIZE;
  198. }
  199.  
  200. void
  201. handle(void)
  202. {
  203.     int rover;
  204.  
  205.     for (rover = 0; rover < MAXROOMS; rover++)
  206.     if (stricmp(roomTab[rover].rtname, msgBuf.mbroom) == 0) {
  207.         countTab[rover].c_messages++;
  208.         return;
  209.     }
  210. }
  211.  
  212. int
  213. sortCount(const struct cTab *p1, const struct cTab *p2)
  214. {
  215.     int diff;
  216.  
  217.     diff = (sorted & SORTSIZE) ? (p2->c_messages - p1->c_messages) : 0;
  218.     
  219.     if (diff == 0 && (sorted & SORTZED))
  220.     diff = p2->c_forgot - p1->c_forgot;
  221.  
  222.     return diff;
  223. }
  224.  
  225. main(int argc, char **argv)
  226. {
  227.     PATHBUF logFile;
  228.     int Index;
  229.     int logCount = 0, forgotCount = 0;
  230.  
  231.     printf("%s for Fnordadel V%s\n", program, VERSION);
  232.     fprintf(stderr, "Munching...\n");
  233.     if (readSysTab(FALSE)) {
  234.     initlogBuf(&logBuf);
  235.     countTab = (struct cTab *) xmalloc(MAXROOMS * sizeof(struct cTab));
  236.     doflags(argc, argv);    /* references countTab[]! */
  237.  
  238.     ctdlfile(logFile, cfg.sysdir, "ctdllog.sys");
  239.     if ((logfl=dopen(logFile, O_RDONLY)) < 0)
  240.         crashout("Can't open %s", logFile);
  241.  
  242.     for (Index = 0; Index < cfg.logsize; Index++) {
  243.         getlog(&logBuf, Index, logfl);
  244.         if readbit(logBuf,uINUSE) {
  245.         logCount++;
  246.         forgotCount += mulchAcct();
  247.         }
  248.         fprintf(stderr, "%d\r", Index);
  249.     }
  250.  
  251.     if (domesg)
  252.         doMessages();
  253.  
  254.     if (sorted)
  255.         qsort((void *)countTab, (size_t)MAXROOMS, sizeof countTab[0],
  256.         (int (*)(const void *, const void *))sortCount);
  257.     display(logCount, forgotCount);
  258.     killlogBuf(&logBuf);
  259.     }
  260.     if (fromdesk())
  261.     hitkey();
  262. }
  263.  
  264. int
  265. mulchAcct(void)
  266. {
  267.     int i, j, g, usedForget;
  268.  
  269.     usedForget = 0;
  270.     for (i = 0;  i < MAXROOMS;    i++) {
  271.     if (readbit(roomTab[i],PUBLIC) || allowall) {
  272.         if ((logBuf.lbgen[i] >> GENSHIFT) != roomTab[i].rtgen)  {
  273.         j = roomTab[i].rtgen - (logBuf.lbgen[i] >> GENSHIFT);
  274.         if (j < 0)
  275.             g = -j;
  276.         else
  277.             g = j;
  278.         if (g == FORGET_OFFSET) {
  279.             usedForget = 1;
  280.             (countTab[i].c_forgot)++;
  281.         }
  282.         }
  283.     }
  284.     }
  285.     return usedForget;
  286. }
  287.